package com.mamingchao.concurrent.four_thread_creation_way;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.locks.ReentrantLock;

/**
 * execute 是立即执行，submite是提交，返回一个future
 *
 * Created by mamingchao on 2020/9/22.
 */
public class ExcutorServiceWay {

    static ReentrantLock fairLock = new ReentrantLock(true);

    public static void main(String[] args) {

        //创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
//        ExecutorService fixServices =  Executors.newFixedThreadPool(2);
//
//        fixServices.execute(new Runnable() {
//            @Override
//            public void run() {
//                char a = 'A';
//                for (int i = 0; i <26; i++) {
//                    fairLock.lock();
//                    System.out.println(a);
//                    a++;
//                    fairLock.unlock();
//                }
//            }
//        });


        //创建一个可缓存线程池，按需创建线程；60s没人用，回收线程；没到60s idle的线程，回被reuse
//        ExecutorService cachedServices =Executors.newCachedThreadPool();

//        cachedServices.execute(new Runnable() {
//            @Override
//            public void run() {
//                for (int i = 0; i <26; i++) {
//                    fairLock.lock();
//                    System.out.println(i);
//                    fairLock.unlock();
//                }
//            }
//        });




        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

        /*
            这个是延迟 指定时间，执行 runnable
         */
//        System.out.println(System.currentTimeMillis());
//        scheduledThreadPool.schedule(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println("I was executed 2 seconds later");
//                System.out.println(System.currentTimeMillis());
//            }
//        },2,TimeUnit.SECONDS);


        /**
         * 延迟 initialDelay的时间开始执行，然后每隔period 循环执行
         *
         * scheduleAtFixedRate如果执行时间小于指定的间隔时间的情况下，callable或runnable每隔period执行一次，
         * 如果执行时间大于指定的间隔时间，每隔程序执行时间执行一次。
         *
         * @param initialDelay the time to delay first execution
         * @param period the period between successive executions
         */
//        scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println(new Date());
//            }
//        },2,1,TimeUnit.SECONDS);


        /**
         * 看注释，这个跟 scheduleAtFixedRate 差不太多
         *
         * scheduleWithFixedDelay,不管执行时间怎么样，两次执行时间之间必须间隔delay时间
         *
         * @param initialDelay the time to delay first execution
         * @param delay the delay between the termination of one
         * execution and the commencement of the next
         */
//        scheduledThreadPool.scheduleWithFixedDelay(new Runnable() {
//            @Override
//            public void run() {
//                System.out.println(new Date());
//            }
//        },2,1,TimeUnit.SECONDS);


        /**
         * @param callable the function to execute
         * @param delay the time from now to delay execution
         * @param unit the time unit of the delay parameter
         */
//        ScheduledFuture<Object> result = scheduledThreadPool.schedule(new Callable<Object>() {
//            /**
//             * Computes a result, or throws an exception if unable to do so.
//             *
//             * @return computed result
//             * @throws Exception if unable to compute a result
//             */
//            @Override
//            public Object call() throws Exception {
//                return new Date();
//            }
//        },1,TimeUnit.SECONDS);
//
//        try {
//            System.out.println(result.get());
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } catch (ExecutionException e) {
//            e.printStackTrace();
//        }

        /**
         * 这个单一线程如果失败了，会重新创建一个线程，继续工作；
         * 这个线程一直会工作，处理一个无边界的队列里的任务
         *
         * 这个线程跟等效的 newFixedThreadPool(1) 不一样，保证这个executor不会重新
         * 配置使用其他的线程
         *
         * Creates an Executor that uses a single worker thread operating
         * off an unbounded queue. (Note however that if this single
         * thread terminates due to a failure during execution prior to
         * shutdown, a new one will take its place if needed to execute
         * subsequent tasks.)  Tasks are guaranteed to execute
         * sequentially, and no more than one task will be active at any
         * given time. Unlike the otherwise equivalent
         * {@code newFixedThreadPool(1)} the returned executor is
         * guaranteed not to be reconfigurable to use additional threads.
         */
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        singleThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("hah");
            }
        });

    }
}
